﻿#include "screenscutcheon.h"
#include "core/guid.h"
#include "graphic/overlay.h"
#include "core/stringvector.h"

using namespace EarthView::World::Core;
using namespace EarthView::World::Graphic;
using namespace EarthView::World::Spatial3D::Controls;
using namespace EarthView::World::Spatial::Math;


			CScreenScutcheon:: CScreenScutcheon(const EVString& name, const EVString& templateName,  CGlobeControl* control)
			{
				this->mName=name;
				this->mpGlobeControl=control;
				this->mpOverlay=NULL;
				this->mpPanelElement=NULL;
				this->mpPanelElementParent=NULL;
				this->mpTextElement=NULL;
				this->mHeight=0;
				this->mWidth=0;
				this->mPosition=CVector2(0,0);
				this->mVisible=true;
				this->mIsSelected=false;
				this->mIsSelectable=false;
				this->mIsDraggable=false;
				this->mpEventObject=NULL;
				this->mpOverlay = COverlayManager::getSingleton().create(this->mName, this->mpGlobeControl->getSceneManager());
				if (mpOverlay)
				{
					this->mpPanelElement= (CBorderPanelOverlayElement*)COverlayManager::getSingletonPtr()->createOverlayElementFromTemplate(templateName, "BorderPanel", name);
					mpOverlay->add2D(mpPanelElement);
				}
			}

			void CScreenScutcheon::setZOrder(ev_uint16 zorder)
			{
				if (mpOverlay)
				{
					mpOverlay->setZOrder(zorder);
				}
			}

			CScreenScutcheon::~CScreenScutcheon()
			{
				if (this->mpOverlay)
				{
					for(ev_size_t i = 0; i < mChildrenNames.size(); i++)
					{
						COverlayManager::getSingleton().destroyOverlayElement(mChildrenNames[i]);
					}
					COverlayManager::getSingleton().destroyOverlayElement(this->mName);
					COverlayManager::getSingleton().destroy(mpOverlay);
					mpOverlay = NULL;
				}
			}

			void CScreenScutcheon::addChildName(const EVString& name)
			{
				for(ev_size_t i = 0; i < mChildrenNames.size(); i++)
				{
					if(mChildrenNames[i] == name)
					{
						return;
					}
				}
				mChildrenNames.push_back(name);
			}

			void CScreenScutcheon::setTextElementFontName(const EVString& panelElementName, const EVString& textAreaName, const EVString& fontName)
			{
				/*CFontPtr font = CFontManager::getSingleton().getFont(FontStyle(fontName, 13, false, false, false), CFontManager::SCREEN_STATUS_OVERLAY);
				if (!font->isLoaded())
				{
					font->load();
				}*/

				/*CFontPtr font = CFontManager::getSingleton().getByName(fontName);
				if (font.isNull())
				{
					font = CFontManager::getSingleton().getFont(FontStyle(fontName, 13, false, false, false),
						CFontManager::SCREEN_STATUS_OVERLAY);
					if (!font->isLoaded())
					{
						font->load();
					}
				}

				this->mpTextElement = this->getTextElement(panelElementName,textAreaName);
				if(mpTextElement)
				{
					this->mpTextElement->setFontName(font->getName());
				}*/
				mpTextElement->setFontStyle(FontStyle(fontName, 13, false, false, false));
			}

			void CScreenScutcheon::setPanelElementHeight(const EVString& panelElementName , const int& height)
			{
				this->mHeight=height;
				this->mpPanelElement=this->getPanelElement(panelElementName);
				if (mpPanelElement)
				{
					this->mpPanelElement->setHeight(height);
				}
			}

			void CScreenScutcheon::setPanelElementWidth(const EVString& panelElementName, const int& width)
			{
				this->mWidth=width;
				this->mpPanelElement=this->getPanelElement(panelElementName);
				if (mpPanelElement)
				{
					this->mpPanelElement->setWidth(width);
				}
			}

			void CScreenScutcheon::setPanelElementPostion(const EVString& panelElementName, const CVector2& pos)
			{
				this->mPosition=pos;
				this->mpPanelElement=this->getPanelElement(panelElementName);
				if(mpPanelElement)
				{
					this->mpPanelElement->setLeft(pos.x);
					this->mpPanelElement->setTop(pos.y);
				}
			}

			void CScreenScutcheon::setTextElementCaption(const EVString& panelElementName, const EVString& textAreaName,  const EVString& value)
			{
				this->mpTextElement = this->getTextElement(panelElementName,textAreaName);
				this->mpPanelElement = this->getPanelElement(panelElementName);
				if(mpTextElement)
				{
					this->mpTextElement->setCaption(value);
				}
			}

			EVString CScreenScutcheon::getTextElementCaption(const EVString& panelElementName, const EVString& textAreaName) 
			{
				EVString caption="";
				this->mpTextElement=this->getTextElement(panelElementName,textAreaName);
				if(mpTextElement)
				{
					caption=this->mpTextElement->getCaption();
				}
				return caption;
			}

			EVString CScreenScutcheon::getTextElementFontName(const EVString& panelElementName, const EVString& textAreaName) 
			{
				EVString fontName="";
				this->mpTextElement=this->getTextElement(panelElementName,textAreaName);
				if(mpTextElement)
				{
					fontName= this->mpTextElement->getFontStyle().getFontFamily();
				}
				return fontName ;
			}

			int CScreenScutcheon::getPanelElementHeight(const EVString& panelElementName ) 
			{
				this->mpPanelElement=this->getPanelElement(panelElementName);
				if (mpPanelElement)
				{
					return this->mpPanelElement->getHeight();
				}
				return 0;
			}

			int CScreenScutcheon::getPanelElementWidth(const EVString& panelElementName) 
			{
				this->mpPanelElement=this->getPanelElement(panelElementName);
				if (mpPanelElement)
				{
					return this->mpPanelElement->getWidth();
				}
				return 0;
			}

			CVector2 CScreenScutcheon::getPanelElementPostion(const EVString& panelElementName) 
			{
				CVector2 pos;
				this->mpPanelElement=this->getPanelElement(panelElementName);
				if(mpPanelElement)
				{
					pos.x=this->mpPanelElement->getLeft();
					pos.y= this->mpPanelElement->getTop();
				}
				return pos;
			}

			bool CScreenScutcheon::isInBoundingBox( const int& x, const int& y)
			{
				CBorderPanelOverlayElement* panelElement=
					dynamic_cast<CBorderPanelOverlayElement*>(this->mpOverlay->getChild(this->mName));
				int left = panelElement->getLeft();
				int top = panelElement->getTop();
				bool m1=  x>=left && x<=left+panelElement->getWidth();
				bool m2= y>=top && y<=top+panelElement->getHeight();
				bool m=m1 && m2;
				if (m)
				{
					return true;
				}
				return false;
			}

			CTextAreaOverlayElement* CScreenScutcheon::getTextElement( const EVString& panelElementName,const EVString& textAreaName )
			{
				this->mpPanelElement=this->getPanelElement(panelElementName);
				if (this->mpPanelElement)
				{
					this->mpTextElement=dynamic_cast<CTextAreaOverlayElement*>(mpPanelElement->getChild(textAreaName));
				}
				return this->mpTextElement;
			}

			CBorderPanelOverlayElement* CScreenScutcheon::getPanelElement( const EVString& panelElementName )
			{
				this->mpPanelElement=dynamic_cast<CBorderPanelOverlayElement*>(this->mpOverlay->getChild(this->mName));
				mStringVector=CStringUtil::split(panelElementName,'/');
				if (mStringVector.size()==1)
				{
					return mpPanelElement;
				} 
				else
				{
					ev_uint32 i = 1;
					this->getChildPanelElement(mName,mpPanelElement,i);
				}
				return this->mpPanelElement;
			}

			void CScreenScutcheon::getChildPanelElement( EVString elementName, 
				CBorderPanelOverlayElement* parentPanel,  ev_uint32& i)
			{
				if (i<mStringVector.size())
				{
					elementName +="/"+ mStringVector[i];

					this->mpPanelElement=dynamic_cast<CBorderPanelOverlayElement*>(parentPanel->getChild(elementName));
					if (mpPanelElement)
					{
						getChildPanelElement(elementName,mpPanelElement, ++i);
					}
				}
			}

			void CScreenScutcheon::setPanelElementMaterial( const EVString& panelElementName, const EVString& materialName )
			{
				this->mpPanelElement=this->getPanelElement(panelElementName);
				if (mpPanelElement)
				{
					this->mpPanelElement->setMaterialName(materialName);
					this->mpPanelElement->setBorderMaterialName(materialName);
				}
			}

			void CScreenScutcheon::setPanelElementTexture(const EVString& panelElementName, const EarthView::World::Graphic::CTexturePtr& texturePtr)
			{
				this->mpPanelElement=this->getPanelElement(panelElementName);
				if (mpPanelElement)
				{
					EarthView::World::Graphic::CMaterialPtr material = CMaterialManager::getSingleton().getByName(this->mpPanelElement->getMaterialName());
					material->getTechnique(0)->getPass(0)->getTextureUnitState(0)->setTexture(texturePtr);
				}
			}

			void CScreenScutcheon::setPanelElementBorderTexture(const EVString& panelElementName, const EarthView::World::Graphic::CTexturePtr& texturePtr)
			{
				this->mpPanelElement=this->getPanelElement(panelElementName);
				if (mpPanelElement)
				{
					EarthView::World::Graphic::CMaterialPtr material = CMaterialManager::getSingleton().getByName(this->mpPanelElement->getBorderMaterialName());
					material->getTechnique(0)->getPass(0)->getTextureUnitState(0)->setTexture(texturePtr);
				}
			}

			void CScreenScutcheon::setEventObject(CScreenScutcheonEventObject* object)
			{
				this->mpEventObject = object;
			}

			CScreenScutcheonEventObject* CScreenScutcheon::getEventObject() const
			{
				return this->mpEventObject;
			}

			void CScreenScutcheon::setTextElementFontColor( const EVString& panelElementName, const EVString& textAreaName, const CColourValue& color )
			{
				this->mpTextElement=this->getTextElement(panelElementName,textAreaName);
				if(mpTextElement)
				{
					this->mpTextElement->setColour(color);
				}
			}

			CColourValue CScreenScutcheon::getTextElementFontColor( const EVString& panelElementName, const EVString& textAreaName )
			{
				CColourValue color=CColourValue::White;
				this->mpTextElement=this->getTextElement(panelElementName,textAreaName);
				if(mpTextElement)
				{
					color= this->mpTextElement->getColour();
				}
				return color;
			}

			void CScreenScutcheon::setTextElementFontColorTop(const EVString& panelElementName, const EVString& textAreaName, const CColourValue& color)
			{
				this->mpTextElement=this->getTextElement(panelElementName,textAreaName);
				if(mpTextElement)
				{
					this->mpTextElement->setColourTop(color);
				}
			}

			CColourValue CScreenScutcheon::getTextElementFontColorTop(const EVString& panelElementName, const EVString& textAreaName)
			{
				CColourValue color=CColourValue::White;
				this->mpTextElement=this->getTextElement(panelElementName,textAreaName);
				if(mpTextElement)
				{
					color= this->mpTextElement->getColourTop();
				}
				return color;
			}

			void CScreenScutcheon::setTextElementFontColorBottom(const EVString& panelElementName, const EVString& textAreaName, const CColourValue& color)
			{
				this->mpTextElement=this->getTextElement(panelElementName,textAreaName);
				if(mpTextElement)
				{
					this->mpTextElement->setColourBottom(color);
				}
			}

			CColourValue CScreenScutcheon::getTextElementFontColorBottom(const EVString& panelElementName, const EVString& textAreaName)
			{
				CColourValue color=CColourValue::White;
				this->mpTextElement=this->getTextElement(panelElementName,textAreaName);
				if(mpTextElement)
				{
					color= this->mpTextElement->getColourBottom();
				}
				return color;
			}

			void CScreenScutcheon::setTextElementFontSize( const EVString& panelElementName, const EVString& textAreaName, const Real& size )
			{
				this->mpTextElement=this->getTextElement(panelElementName,textAreaName);
				if(mpTextElement)
				{
					this->mpTextElement->setCharHeight(size);
				}
			}

			Real CScreenScutcheon::getTextElementFontSize( const EVString& panelElementName, const EVString& textAreaName )
			{
				int size=0;
				this->mpTextElement=this->getTextElement(panelElementName,textAreaName);
				if(mpTextElement)
				{
					size = this->mpTextElement->getCharHeight();
				}
				return size;
			}

			void CScreenScutcheon::setTextElementFontHasShadow(const EVString& panelElementName, const EVString& textAreaName, const ev_bool& hasShadow)
			{
				const EVString& fontName = this->getTextElement(panelElementName, textAreaName)->getFontStyle().getFontFamily();
				mpFont = CFontManager::getSingleton().getFont(FontStyle(fontName, this->getTextElementFontSize(panelElementName, textAreaName), false, false, hasShadow), CFontManager::SCREEN_STATUS_OVERLAY);
				//mpFont->load();

				this->setTextElementFontName(panelElementName, textAreaName, mpFont->getName());
			}

			void CScreenScutcheon::calculateWidth(EarthView::World::Graphic::CTextAreaOverlayElement* pTextArea, _out Real& width, _out Real& height)
			{
				CFont* font = (CFont*)CFontManager::getSingleton().getByName(pTextArea->getFontStyle().getFontFamily()).getPointer();
				DisplayString current = pTextArea->getCaption();
				Real spaceWidth = pTextArea->getSpaceWidth();
				Real charHeight = pTextArea->getCharHeight();
				Real tempWidth = 0;
				ev_int32 rowCount = 1;
				DisplayString::iterator i,iend;
				iend = current.end();
				// 循环从第一个字符开始
				for(i = current.begin(); i != iend; ++i)
				{
					// 如果字符为' '
					if(*i == ' ')
					{
						if(spaceWidth != 0)
							tempWidth += spaceWidth;
						else
							tempWidth += font->getGlyphAspectRatio(' ') * font->getFontStyle().size();
					}
					else if(*i == '\n') // 如果字符为'\n'
					{
						if(width < tempWidth)
							width = tempWidth;
						tempWidth = 0; 
						rowCount++;
					}
					else
						tempWidth += font->getGlyphAspectRatio(*i) * font->getFontStyle().size();
				}
				if(width == 0)
				{
					width = tempWidth;
				}
				height = charHeight * rowCount;
			}

			void CScreenScutcheon::setPanelElementVisible(const EVString& panelElementName, ev_bool isVisible)
			{
				this->mpPanelElement = this->getPanelElement(panelElementName);
				if(this->mpPanelElement)
				{
					if(isVisible)
					{
						this->mpPanelElement->show();
					}
					else
					{
						this->mpPanelElement->hide();
					}
				}
			}

			ev_bool CScreenScutcheon::getPanelElementVisible(const EVString& panelElementName)
			{
				this->mpPanelElement = this->getPanelElement(panelElementName);
			    if(this->mpPanelElement)
				{
					return this->mpPanelElement->isVisible();
				}
				return false;
			}

			void CScreenScutcheon::setTextElementVisible(const EVString& panelElementName, const EVString& textAreaName, ev_bool isVisible)
			{
				this->mpTextElement = this->getTextElement(panelElementName,textAreaName);
				if(this->mpTextElement)
				{
					if(isVisible)
					{
						this->mpTextElement->show();
					}
					else
					{
						this->mpTextElement->hide();
					}
				}
			}

			ev_bool CScreenScutcheon::getTextElementVisible(const EVString& panelElementName, const EVString& textAreaName)
			{
				this->mpTextElement = this->getTextElement(panelElementName,textAreaName);
				if(this->mpTextElement)
				{
					return this->mpTextElement->isVisible();
				}
				return false;
			}

